import { isPair as U } from '../nodes/identity.js';
import { Pair as $ } from '../nodes/Pair.js';
import { YAMLMap as v } from '../nodes/YAMLMap.js';
import { YAMLSeq as A } from '../nodes/YAMLSeq.js';
import { resolveEnd as R } from './resolve-end.js';
import { resolveProps as P } from './resolve-props.js';
import { containsNewline as q } from './util-contains-newline.js';
import { mapIncludes as B } from './util-map-includes.js';
const O = 'Block collections are not allowed within flow collections',
  S = d => d && (d.type === 'block-map' || d.type === 'block-seq');
function j({ composeNode: d, composeEmptyNode: N }, n, p, t, b) {
  const I = p.start.source === '{',
    f = I ? 'flow map' : 'flow sequence',
    K = (b == null ? void 0 : b.nodeClass) ?? (I ? v : A),
    i = new K(n.schema);
  i.flow = !0;
  const C = n.atRoot;
  C && (n.atRoot = !1);
  let g = p.offset + p.start.source.length;
  for (let o = 0; o < p.items.length; ++o) {
    const k = p.items[o],
      { start: T, key: h, sep: a, value: m } = k,
      e = P(T, {
        flow: f,
        indicator: 'explicit-key-ind',
        next: h ?? (a == null ? void 0 : a[0]),
        offset: g,
        onError: t,
        startOnNewline: !1,
      });
    if (!e.found) {
      if (!e.anchor && !e.tag && !a && !m) {
        o === 0 && e.comma
          ? t(e.comma, 'UNEXPECTED_TOKEN', `Unexpected , in ${f}`)
          : o < p.items.length - 1 &&
            t(e.start, 'UNEXPECTED_TOKEN', `Unexpected empty item in ${f}`),
          e.comment &&
            (i.comment
              ? (i.comment +=
                  `
` + e.comment)
              : (i.comment = e.comment)),
          (g = e.end);
        continue;
      }
      !I &&
        n.options.strict &&
        q(h) &&
        t(
          h,
          // checked by containsNewline()
          'MULTILINE_IMPLICIT_KEY',
          'Implicit keys of flow sequence pairs need to be on a single line',
        );
    }
    if (o === 0)
      e.comma && t(e.comma, 'UNEXPECTED_TOKEN', `Unexpected , in ${f}`);
    else if (
      (e.comma || t(e.start, 'MISSING_CHAR', `Missing , between ${f} items`),
      e.comment)
    ) {
      let c = '';
      e: for (const s of T)
        switch (s.type) {
          case 'comma':
          case 'space':
            break;
          case 'comment':
            c = s.source.substring(1);
            break e;
          default:
            break e;
        }
      if (c) {
        let s = i.items[i.items.length - 1];
        U(s) && (s = s.value ?? s.key),
          s.comment
            ? (s.comment +=
                `
` + c)
            : (s.comment = c),
          (e.comment = e.comment.substring(c.length + 1));
      }
    }
    if (!I && !a && !e.found) {
      const c = m ? d(n, m, e, t) : N(n, e.end, a, null, e, t);
      i.items.push(c), (g = c.range[2]), S(m) && t(c.range, 'BLOCK_IN_FLOW', O);
    } else {
      const c = e.end,
        s = h ? d(n, h, e, t) : N(n, c, T, null, e, t);
      S(h) && t(s.range, 'BLOCK_IN_FLOW', O);
      const l = P(a ?? [], {
        flow: f,
        indicator: 'map-value-ind',
        next: m,
        offset: s.range[2],
        onError: t,
        startOnNewline: !1,
      });
      if (l.found) {
        if (!I && !e.found && n.options.strict) {
          if (a)
            for (const u of a) {
              if (u === l.found) break;
              if (u.type === 'newline') {
                t(
                  u,
                  'MULTILINE_IMPLICIT_KEY',
                  'Implicit keys of flow sequence pairs need to be on a single line',
                );
                break;
              }
            }
          e.start < l.found.offset - 1024 &&
            t(
              l.found,
              'KEY_OVER_1024_CHARS',
              'The : indicator must be at most 1024 chars after the start of an implicit flow sequence key',
            );
        }
      } else
        m &&
          ('source' in m && m.source && m.source[0] === ':'
            ? t(m, 'MISSING_CHAR', `Missing space after : in ${f}`)
            : t(l.start, 'MISSING_CHAR', `Missing , or : between ${f} items`));
      const _ = m ? d(n, m, l, t) : l.found ? N(n, l.end, a, null, l, t) : null;
      _
        ? S(m) && t(_.range, 'BLOCK_IN_FLOW', O)
        : l.comment &&
          (s.comment
            ? (s.comment +=
                `
` + l.comment)
            : (s.comment = l.comment));
      const y = new $(s, _);
      if ((n.options.keepSourceTokens && (y.srcToken = k), I)) {
        const u = i;
        B(n, u.items, s) && t(c, 'DUPLICATE_KEY', 'Map keys must be unique'),
          u.items.push(y);
      } else {
        const u = new v(n.schema);
        (u.flow = !0), u.items.push(y), i.items.push(u);
      }
      g = _ ? _.range[2] : l.end;
    }
  }
  const M = I ? '}' : ']',
    [w, ...L] = p.end;
  let r = g;
  if (w && w.source === M) r = w.offset + w.source.length;
  else {
    const o = f[0].toUpperCase() + f.substring(1),
      k = C
        ? `${o} must end with a ${M}`
        : `${o} in block collection must be sufficiently indented and end with a ${M}`;
    t(g, C ? 'MISSING_CHAR' : 'BAD_INDENT', k),
      w && w.source.length !== 1 && L.unshift(w);
  }
  if (L.length > 0) {
    const o = R(L, r, n.options.strict, t);
    o.comment &&
      (i.comment
        ? (i.comment +=
            `
` + o.comment)
        : (i.comment = o.comment)),
      (i.range = [p.offset, r, o.offset]);
  } else i.range = [p.offset, r, r];
  return i;
}
export { j as resolveFlowCollection };
